package com.ruoyi.weiriya.service.impl;

import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.core.domain.entity.WVehicle;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.kit.core.enums.OrderStateEnums;
import com.ruoyi.weiriya.domain.*;
import com.ruoyi.weiriya.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.weiriya.mapper.WMemberMapper;
import com.ruoyi.common.core.domain.entity.WMember;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;


/**
 * 用户信息Service业务层处理
 * 
 * @author lynn
 * @date 2023-08-01
 */
@Service
public class WMemberServiceImpl extends ServiceImpl<WMemberMapper, WMember> implements IWMemberService
{
    @Autowired
    private WMemberMapper memberMapper;

    @Autowired
    private IWOrderService orderService;

    @Autowired
    private IWAreaService areaService;

    @Autowired
    private IWMessageService messageService;

    @Autowired
    private IWLeaveWordService leaveWordService;

    @Autowired
    private IWPayVipRecordService payVipRecordService;

    @Autowired
    private IWVehicleService vehicleService;

    @Autowired
    private IWCompanyService companyService;

    @Autowired
    private IWVipSettingService vipSettingService;


    @Override
    public List<WMember> getList(WMember member) {
        QueryWrapper<WMember> queryWrapper = member.queryWrapper();
        if(StringUtils.isNotBlank(SecurityUtils.getLoginUser().getUser().getCompanyId())){
            List<String> areaIdListByUserId = companyService.getAreaIdList();
            if(areaIdListByUserId.size() > 0) {
                queryWrapper.in("a.id", areaIdListByUserId);
            } else {
                return new ArrayList<>();
            }
        }
        List<WMember> list = memberMapper.getList(queryWrapper);
        for (WMember wMember : list) {
            wMember.setPassword("");
        }
        return list;
    }

    @Override
    public Map statistics() {
        Long userId = SecurityUtils.getUserId();
        WMember member = this.getById(userId);
        Map<String, Object> map = new HashMap<>();
        // 订单数量
        long orderNum = orderService.count(new LambdaQueryWrapper<WOrder>()
                .eq(WOrder::getMemberId, userId));
        map.put("orderNum", orderNum);
        // 未读消息数量
        long messageNum = messageService.count(new LambdaQueryWrapper<WMessage>()
                .eq(WMessage::getMemberId, userId)
                .eq(WMessage::getUserType, 2)
                .eq(WMessage::getMessageRange, 1)
                .eq(WMessage::getState, 1));
        // 未读反馈回复数量
//        long leaveWordNum = leaveWordService.count(new LambdaQueryWrapper<WLeaveWord>()
//                .eq(WLeaveWord::getMemberId, userId)
//                .eq(WLeaveWord::getState, 1));
        map.put("messageNum", messageNum);
        // 地址
        if(StringUtils.isNotBlank(member.getAreaId())) {
            WArea area = areaService.getById(member.getAreaId());
            map.put("areaName", area.getName());
        }else{
            map.put("areaName", "");
        }
        // 当前会员开始和结束时间
        // 校验会员级别
        Date now = new Date();
        if(member.getVipType() != 4) {
            WPayVipRecord payVipRecord = payVipRecordService.getOne(new LambdaQueryWrapper<WPayVipRecord>()
                    .eq(WPayVipRecord::getMemberId, member.getId())
                    .eq(WPayVipRecord::getType, member.getMemberType())
                    .ge(WPayVipRecord::getEndTime, now)
                    .le(WPayVipRecord::getStartTime, now));
            String start = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, payVipRecord.getStartTime());
            String end = DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD, payVipRecord.getEndTime());
            map.put("vipTime", start + "——" + end);
        } else {
            map.put("vipTime", "暂无");
        }
        return map;
    }

    @Override
    public WMember getWMemberById(String id) {
        WMember member = memberMapper.getWMemberById(id);
        member.setPassword("");
        WVehicle vehicle = vehicleService.getWVehicleByMemberId(member.getId());
        member.setVehicle(vehicle);
        if(StringUtils.isNull(vehicle)){
            member.setVehicle(new WVehicle());
        }
        return member;
    }

    @Override
    public void updateMemberTask() {
        // 获取所有会员用户
        List<WMember> list = this.list(new LambdaQueryWrapper<WMember>()
                .eq(WMember::getStatus, 1)
                .le(WMember::getMemberType, 2)
                .le(WMember::getVipType, 3)
                .le(WMember::getVipEndTime, DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date())));
        // 接收发生变化的用户
        ArrayList<WMember> memberList = new ArrayList<>();
        // 获取当前时间
        Date now = new Date();
        for (WMember member : list) {
            // 比较会员结束时间
            Date vipEndTime = member.getVipEndTime();
            boolean isChange = false;
            if(now.compareTo(vipEndTime) > 0){
                member.setVipType(4);
                isChange = true;
            } else {
                // 校验会员级别
                WPayVipRecord payVipRecord = payVipRecordService.getOne(new LambdaQueryWrapper<WPayVipRecord>()
                        .eq(WPayVipRecord::getMemberId, member.getId())
                        .eq(WPayVipRecord::getType,member.getMemberType())
                        .le(WPayVipRecord::getEndTime, now)
                        .ge(WPayVipRecord::getStartTime, now));
                if(StringUtils.isNull(payVipRecord)){
                    member.setVipType(4);
                    isChange = true;
                } else if(member.getVipType() != payVipRecord.getVipType()){
                    member.setVipType(payVipRecord.getVipType());
                    isChange = true;
                }
            }

            if(isChange) {
                memberList.add(member);
            }
        }
        if(memberList.size() > 0) {
            // 更新发生变化的用户
            this.updateBatchById(memberList);
        }
    }

    @Transactional
    @Override
    public boolean saveWMember(WMember wMember) {
        // 检查用户信息
        checkMember(wMember);
        // 初始化用户信息
        initMember(wMember);
        // 检查车辆信息
        WVehicle vehicle = wMember.getVehicle();
        checkVehicle(vehicle);
        // 保存用户信息
        this.saveOrUpdate(wMember);

        // 如果是会员则保存用户会员信息记录
        initAndSavePayVipRecord(wMember);

        // 初始化车辆信息
        vehicle.setMemberId(wMember.getId());
        // 保存车辆信息
        vehicleService.saveOrUpdate(vehicle);

        // 创建会员购买订单
        createOrder(wMember, vehicle);
        return true;
    }

    private void createOrder(WMember wMember, WVehicle vehicle) {
        Integer memberType = wMember.getMemberType();
        Integer vipType = wMember.getVipType();

        if(memberType == 3 || vipType == 4) {
            return;
        }

        String areaId = wMember.getAreaId();
        WVipSetting vipSetting = vipSettingService.getOne(new LambdaQueryWrapper<WVipSetting>()
                .eq(WVipSetting::getAreaId, areaId)
                .eq(memberType == 1, WVipSetting::getVehicleType, vehicle.getVehicleChargeTypeId())
                .eq(memberType == 2, WVipSetting::getVehicleType, vehicle.getVehicleNonChargeTypeId()));
        if(StringUtils.isNull(vipSetting)){
            throw new ServiceException("该点位未设置所选车辆类型的价格！");
        }
        WOrder order = new WOrder();
        order.setAreaId(areaId);
        order.setMemberId(wMember.getId());
        order.setSn("sn" + DateUtils.dateTimeNow(DateUtils.YYMMDD) + IdUtil.getSnowflake().nextIdStr());
        order.setMemberType(1);
        order.setOrderStatus(OrderStateEnums.PAID.name());
        order.setCompleteTime(new Date());
        order.setPayType(2);
        order.setCreateTime(new Date());
        order.setCreateBy(SecurityUtils.getUserId().toString());
        if(vipType == 1){
            order.setGoodsType("MONTH_DEPOSIT");
            if(StringUtils.isNull(vipSetting.getMonthAmount()) || vipSetting.getMonthAmount() <= 0){
                throw new ServiceException("该点位未设置所选车辆类型的价格！");
            }
            order.setGoodsPrice(vipSetting.getMonthAmount());
            order.setFinalPrice(vipSetting.getMonthAmount());
            if(memberType == 1){
                order.setGoodsType("MONTH_CHARGE");
            }
        } else if(vipType == 2){
            order.setGoodsType("QUARTER_DEPOSIT");
            if(StringUtils.isNull(vipSetting.getQuarterAmount()) || vipSetting.getQuarterAmount() <= 0){
                throw new ServiceException("该点位未设置所选车辆类型的价格！");
            }
            order.setGoodsPrice(vipSetting.getQuarterAmount());
            order.setFinalPrice(vipSetting.getQuarterAmount());
            if(memberType == 1){
                order.setGoodsType("QUARTER_CHARGE");
            }
        } else if(vipType == 3){
            order.setGoodsType("YEAR_DEPOSIT");
            if(StringUtils.isNull(vipSetting.getYearAmount()) || vipSetting.getYearAmount() <= 0){
                throw new ServiceException("该点位未设置所选车辆类型的价格！");
            }
            order.setGoodsPrice(vipSetting.getYearAmount());
            order.setFinalPrice(vipSetting.getYearAmount());
            if(memberType == 1){
                order.setGoodsType("YEAR_CHARGE");
            }
        }
        if(StringUtils.isNotNull(wMember.getVipPrice())) {
//            order.setGoodsPrice(wMember.getVipPrice());
            order.setFinalPrice(wMember.getVipPrice());
        }
        orderService.save(order);
    }


    @Transactional
    @Override
    public boolean updateWMemberById(WMember member) {
        // 检查用户信息
        checkMember(member);
        member.setRoleId("100");

        WMember wMember = this.getById(member.getId());

        member.setAreaId(wMember.getAreaId());
        member.setMemberType(wMember.getMemberType());
        member.setVipType(wMember.getVipType());
        member.setVipStartTime(wMember.getVipStartTime());
        member.setVipEndTime(wMember.getVipEndTime());

        // 更新车辆信息
        WVehicle vehicle = wMember.getVehicle();
        if(StringUtils.isNotNull(vehicle)) {
            vehicleService.updateById(vehicle);
        }
        return this.updateById(member);
    }


    public static void main(String[] args) {
        // 冒泡排序
        int[] arr = {1, 3, 2, 5, 4, 6, 7, 9, 8};
        for(int i = 0; i < arr.length - 1; i++) {
            for(int j = 0; j < arr.length - 1 - i; j++) {
                if(arr[j] < arr[j+1]) {
                    int temp = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = temp;
                }

            }
        }
    }

    @Override
    public boolean updateVipById(WMember wMember) {
        WMember member = this.getById(wMember.getId());

        // 保存会员信息
        initAndSavePayVipRecord(wMember);

        member.setAreaId(wMember.getAreaId());
        member.setMemberType(wMember.getMemberType());
        member.setVipType(wMember.getVipType());
        member.setVipStartTime(wMember.getVipStartTime());
        member.setVipEndTime(wMember.getVipEndTime());

        // 获取车辆信息
        WVehicle vehicle = vehicleService.getOne(new LambdaQueryWrapper<WVehicle>()
                .eq(WVehicle::getMemberId, wMember.getId()));
        // 创建会员购买订单
        createOrder(wMember, vehicle);
        return this.updateById(member);
    }

    @Override
    public Map<String, String> editVip(WMember wMember) {
        WMember member = this.getById(wMember.getId());
        Map<String, String> map = new HashMap<>();
        Date now = new Date();
        Date startTime = now;
        if(member.getMemberType().equals(wMember.getMemberType())){
            if (now.before(member.getVipEndTime())) {
                startTime = member.getVipEndTime();
            }
        }
        // 获取车辆信息
        WVehicle vehicle = vehicleService.getOne(new LambdaQueryWrapper<WVehicle>()
                .eq(WVehicle::getMemberId, wMember.getId()));

        Integer memberType = wMember.getMemberType();
        Integer vipType = wMember.getVipType();
        WVipSetting vipSetting = vipSettingService.getOne(new LambdaQueryWrapper<WVipSetting>()
                .eq(WVipSetting::getAreaId, member.getAreaId())
                .eq(WVipSetting::getSettingType, wMember.getMemberType())
                .eq(memberType == 1, WVipSetting::getVehicleType, vehicle.getVehicleChargeTypeId())
                .eq(memberType == 2, WVipSetting::getVehicleType, vehicle.getVehicleNonChargeTypeId()));

        if(StringUtils.isNull(vipSetting)){
            throw new ServiceException("点位价格未设置！");
        }
        Double price;
        Date endTime;
        if(vipType == 1){
            endTime = DateUtils.addMonths(startTime, 1);
            price = vipSetting.getMonthAmount();
        } else if(vipType == 2){
            endTime = DateUtils.addMonths(startTime, 3);
            price = vipSetting.getQuarterAmount();
        } else {
            endTime = DateUtils.addMonths(startTime, 12);
            price = vipSetting.getYearAmount();
        }
        map.put("startTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, startTime));
        map.put("endTime", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, endTime));
        map.put("vipPrice", price + "");

        return map;
    }

    @Transactional
    @Override
    public boolean removeMemberByIds(List<String> ids) {
        this.removeByIds(ids);
        // 删除用户车辆信息
        return vehicleService.remove(new LambdaQueryWrapper<WVehicle>()
                .in(WVehicle::getMemberId, ids));
    }


    private void initAndSavePayVipRecord(WMember wMember) {
        if(wMember.getMemberType() == 1 || wMember.getMemberType() == 2) {
            WPayVipRecord payVipRecord = new WPayVipRecord();
            payVipRecord.setMemberId(wMember.getId());
            payVipRecord.setType(wMember.getMemberType());
            payVipRecord.setVipType(wMember.getVipType());
            payVipRecord.setAmount(0D);
            payVipRecord.setStartTime(wMember.getVipStartTime());
            payVipRecord.setEndTime(wMember.getVipEndTime());
            payVipRecordService.save(payVipRecord);
        }
    }

    private void checkVehicle(WVehicle vehicle) {
        if(StringUtils.isBlank(vehicle.getVehicleChargeTypeId())){
            throw new ServiceException("请选择车辆充电类型！");
        }
        if(StringUtils.isBlank(vehicle.getVehicleNonChargeTypeId())){
            throw new ServiceException("请选择车辆非充电类型！");
        }
    }

    private void initMember(WMember wMember) {
        if(StringUtils.isBlank(wMember.getId())){
            wMember.setWallet(0D);
        }
        wMember.setStatus(1);
        wMember.setRoleId("100");
    }

    private boolean checkMember(WMember wMember) {
        if(StringUtils.isBlank(wMember.getAreaId())){
            throw new ServiceException("请选择用户点位！");
        }
        if(StringUtils.isBlank(wMember.getUserName())){
            throw new ServiceException("请填写用户手机号码！");
        } else {
            if(StringUtils.isNotBlank(wMember.getId())){
                wMember.setUserName(null);
            } else {
                String userName = wMember.getUserName();
                long count = this.count(new LambdaQueryWrapper<WMember>()
                        .eq(WMember::getUserName, userName));
                if(count > 0){
                    throw new ServiceException("账号已存在！");
                }
            }

        }
        if(StringUtils.isNull(wMember.getMemberType())){
            throw new ServiceException("请选择用户类型！");
        }
        if((wMember.getMemberType() == 1 || wMember.getMemberType() == 2) && StringUtils.isNull(wMember.getVipType())){
            throw new ServiceException("请选择会员级别！");
        }
        return true;
    }

}
